package com.yantong.service.impl;

import com.yantong.constant.*;
import com.yantong.exception.BDException;
import com.yantong.mapper.*;
import com.yantong.pojo.*;
import com.yantong.service.CentreService;
import com.yantong.service.CommissionService;
import com.yantong.service.ConfigService;
import com.yantong.utils.DateUtils;
import com.yantong.utils.PageUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author kanghaixin
 * @date 2018/9/18.21:21
 */
@Service
public class CommissionServiceImpl implements CommissionService {

    private static final Logger logger = LoggerFactory.getLogger(CommissionServiceImpl.class);
    @Autowired
    private CommissionLogMapper commissionLogMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private BalanceLogMapper balanceLogMapper;
    @Autowired
    private ConfigService configService;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderProductMapper orderProductMapper;
    @Autowired
    @Lazy
    private CentreService centreService;

    @Override
    public PageUtils<CommissionLog> listCommissionLogs(CommisLogsParams params, int offset, int limit) {
        PageUtils<CommissionLog> pageUtils = new PageUtils<>();
        //params.setType(null);
        int total = commissionLogMapper.countByParams(params);
        if (total > 0) {
            List<CommissionLog> list = commissionLogMapper.listByParams(params, new RowBounds(offset, limit));
            for (CommissionLog log : list) {
                //log.setOrderStatusName(OrderStatus.get(log.getOrderStatus()));
                log.setTypeName(CommissionLogType.get(log.getType()));
            }
            pageUtils.setRows(list);
            pageUtils.setTotal(total);
        }
        return pageUtils;
    }

    @Override
    public BigDecimal countCommissionLogs(CommisLogsParams params) {
        BigDecimal allCommision = commissionLogMapper.countCommissionLogs(params);
        if (allCommision == null || !(allCommision.compareTo(BigDecimal.ZERO) > 0)) {
            return BigDecimal.ZERO;
        }
        return allCommision;
    }

    @Override
    public List<CommissionLog> listCommissionLogs(CommisLogsParams params) {
        return commissionLogMapper.listByParams(params);
    }


    @Override
    public Double commissionTotal(Long mid) {
        return commissionLogMapper.commissionTotal(mid);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int grant(Long id, Long userId, String username) {
        if (id == null) {
            return 0;
        }
        CommissionLog log = commissionLogMapper.selectByPrimaryKey(id);
        if (log == null) {
            throw new BDException(BusinessCode.COMMISSION_NOT_FOUND);
        }
        if (log.getDel() == 1 || log.getIsGrant() == 1) {
            throw new BDException(BusinessCode.COMMISSION_GRANT_ALREADY);
        }


        Order order = orderMapper.selectByPrimaryKey(log.getOrderId());
        OrderProduct orderProduct = orderProductMapper.selectByPrimaryKey(log.getOrderProductId());
        if (orderProduct == null ||
                orderProduct.getStatus() == OrderStatus.work_access.getCode() ||
                orderProduct.getStatus() == OrderStatus.wait_send.getCode() ||
                orderProduct.getStatus() == OrderStatus.wait_received.getCode()) {
            return 0;
        }
        /* if (order == null||order.getStatus()==OrderStatus.work_access.getCode()) {
            return 0;
        }*/

        Long mid = log.getMid();
        Balance balance = memberMapper.getBalanceDetail(mid);
        if (balance == null) {
            logger.info("not found member by mid:{}", mid);
            return 0;
        }

        log.setGrantId(userId);
        log.setGrantName(username);
        log.setGrantTime(new Date());
        log.setIsGrant(1);

        BalanceLog balanceLog = new BalanceLog();
        balanceLog.setMid(mid);
        balanceLog.setMobile(balance.getMobile());
        balanceLog.setRealname(balance.getRealname());
        balanceLog.setTitle("手动" + RechargeType.GRANT_COMMISSION.getType());
        balanceLog.setStatus(0);
        balanceLog.setStyle(5);
        balanceLog.setBeforeamount(balance.getBalance());
        balanceLog.setMoney(log.getCommission());
        balanceLog.setAfteramount(balance.getBalance().add(log.getCommission()));
        balanceLog.setCentreId(balance.getCentreId());
        balanceLog.setRemark(order.getOrdersn().concat(",").concat(String.valueOf(log.getOrderProductId())));
        balanceLog.setSource(1);//门店用户余额变更
        balanceLogMapper.insertSelective(balanceLog);
        memberMapper.rechargeBalance(mid, log.getCommission().doubleValue());



        OrderProduct op = new OrderProduct();
        op.setId(log.getOrderProductId());
        op.setStatus(OrderStatus.success.getCode());
        orderProductMapper.updateByPrimaryKeySelective(op);

        order.setStatus(OrderStatus.success.getCode());
        orderMapper.updateByPrimaryKeySelective(order);
        int commissionLog = commissionLogMapper.updateByPrimaryKeySelective(log);
        return commissionLog;
    }

    @Override
    public int grant(CommissionLog cl, String remark) {
        if (cl == null) {
            return 0;
        }

        Long mid = cl.getMid();
        Balance balance = memberMapper.getBalanceDetail(mid);
        if (balance == null) {
            logger.info("not found member by mid:{}", mid);
            return 0;
        }
        Order order = orderMapper.selectByPrimaryKey(cl.getOrderId());
        if (order == null) {
            return 0;
        }

        //扣除商户余额
        centreService.deductAmount(cl.getCentreId(), cl.getCommission(), order.getOrdersn(), cl.getOrderProductId(), 2, remark);

        BalanceLog balanceLog = new BalanceLog();
        balanceLog.setMid(mid);
        balanceLog.setMobile(balance.getMobile());
        balanceLog.setRealname(balance.getRealname());
        balanceLog.setTitle(RechargeType.GRANT_COMMISSION.getType());
        balanceLog.setStatus(0);
        balanceLog.setStyle(5);
        balanceLog.setBeforeamount(balance.getBalance());
        balanceLog.setMoney(cl.getCommission());
        balanceLog.setAfteramount(balance.getBalance().add(cl.getCommission()));
        balanceLog.setCentreId(balance.getCentreId());
        balanceLog.setRemark(cl.getOrderSn() + "," + cl.getOrderProductId());
        balanceLog.setSource(1);//门店用户余额变更
        balanceLogMapper.insertSelective(balanceLog);
        memberMapper.rechargeBalance(mid, cl.getCommission().doubleValue());

        OrderProduct op = new OrderProduct();
        op.setId(cl.getOrderProductId());
        op.setStatus(OrderStatus.success.getCode());
        orderProductMapper.updateByPrimaryKeySelective(op);

        order.setStatus(OrderStatus.success.getCode());
        orderMapper.updateByPrimaryKeySelective(order);
        cl.setIsGrant(1);
        cl.setGrantTime(new Date());
        return commissionLogMapper.updateByPrimaryKeySelective(cl);
    }

    @Override
//	@Async
    public void saveLog(CommissionLog log) {
        if (log == null || log.getCommission() == null) {
            return;
        }
        if (log.getCommission().doubleValue() > 0) {
            commissionLogMapper.insertSelective(log);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoGrant(Long orderProductId) {
        CommissionLogExample example = new CommissionLogExample();
        CommissionLogExample.Criteria criteria = example.createCriteria();
        criteria.andOrderProductIdEqualTo(orderProductId)

                .andDelEqualTo(0);
        List<CommissionLog> logs = commissionLogMapper.selectByExample(example);
        if (!CollectionUtils.isEmpty(logs)) {
            for (CommissionLog log : logs) {
                Long mid = log.getMid();
                if (log.getDel() == 1 || log.getIsGrant() == 1) {
                    continue;
                }
                OrderProduct op = orderProductMapper.selectByPrimaryKey(orderProductId);
                if (op == null) {
                    continue;
                }
                //扣除商户余额     参数2代码站点门店佣金发放  商户余额流程已去除
                centreService.deductAmount(log.getCentreId(), log.getCommission(), op.getOrdersn(), orderProductId, 2, "发佣金扣除商户余额,".concat(op.getProductName()).concat(",销售价:").concat(op.getPrice().toString()).concat(",成本价:").concat(op.getCostprice().multiply(new BigDecimal(op.getTotal())).toString()).concat("订单号："));
//				if (r < 1) {
//					continue;
//				}

                Balance balance = memberMapper.getBalanceDetail(mid);
                if (balance == null) {
                    logger.info("not found member by mid:{}", mid);
                    continue;
                }
                BalanceLog balanceLog = new BalanceLog();
                balanceLog.setMid(mid);
                balanceLog.setMobile(balance.getMobile());
                balanceLog.setRealname(balance.getRealname());
                balanceLog.setTitle("自动" + RechargeType.GRANT_COMMISSION.getType());
                balanceLog.setStatus(0);
                balanceLog.setStyle(5);
                balanceLog.setBeforeamount(balance.getBalance());
                balanceLog.setMoney(log.getCommission());
                balanceLog.setAfteramount(balance.getBalance().add(log.getCommission()));
                balanceLog.setCentreId(balance.getCentreId());
                balanceLog.setRemark(op.getOrdersn().concat(",").concat(String.valueOf(orderProductId)));
                balanceLog.setSource(1);//门店用户余额变更
                balanceLog.setFlowtype("5");//流水类型:门店发佣金
                balanceLogMapper.insertSelective(balanceLog);
                memberMapper.rechargeBalance(mid, log.getCommission().doubleValue());

                log.setIsGrant(1);
                log.setGrantTime(new Date());
                commissionLogMapper.updateByPrimaryKeySelective(log);
            }
        }

    }

    @Override
    public double commissionCount(Long mid, Integer isGrant) {
        return commissionLogMapper.commissionCount(mid, isGrant);
    }


    @Override
    public Map<String, Object> getMidGrantCommissionInfo(Long mid, Integer timeType, int offset, int limit) {
        Map<String, Object> result = new HashMap<>(4);
        Date start = null;
        Date end = null;

        Member member = memberMapper.selectByPrimaryKey(mid);
        if (member == null) {
            logger.info("not found member info by mid:{}", mid);
            return result;
        }
        int startH = 20, startM = 30, endH = 20, endM = 0;
        TradeConfig config = configService.getTradeConfig(member.getCentreId());
        if (config != null) {
            startH = config.getNodeHour() == null ? startH : config.getNodeHour();
            startM = config.getNodeMin() == null ? startM : config.getNodeMin();
            endH = config.getFreeEndHour() == null ? endH : config.getFreeEndHour();
            endM = config.getFreeEndMin() == null ? endM : config.getFreeEndMin();
        }

        if (Objects.equals(timeType, TimeType.ALL.getCode())) {
            result.put("timeType", TimeType.ALL.getName());
        } else if (Objects.equals(timeType, TimeType.TODAY.getCode())) {
            result.put("timeType", TimeType.TODAY.getName());
            start = DateUtils.getAppointTime(DateUtils.getAddDayDate(new Date(), -1), startH, startM);
            end = DateUtils.getAppointTime(new Date(), endH, endM);
        } else if (Objects.equals(timeType, TimeType.WEEK.getCode())) {
            result.put("timeType", TimeType.WEEK.getName());

            start = DateUtils.getAppointTime(DateUtils.getWeekFirstDay(), startH, startM);
            end = DateUtils.getAppointTime(new Date(), endH, endM);
        } else {
            result.put("timeType", TimeType.MONTH.getName());
            start = DateUtils.getAppointTime(DateUtils.getAddDayDate(DateUtils.getMonthStart(), -1), startH, startM);
            end = DateUtils.getAppointTime(new Date(), endH, endM);
        }
        result.put("commissionTotal", commissionLogMapper.getMidGrantCommissionTotal(mid, start, end));

        CommisLogsParams clp = new CommisLogsParams();
        clp.setMid(mid);
        if (start != null) {
            clp.setCreateTimeStart(start);
        }
        if (end != null) {
            clp.setCreateTimeEnd(end);
        }

        PageUtils<CommissionLog> logs = new PageUtils<>();
        int total = commissionLogMapper.countByParams(clp);
        if (total > 0) {
            logs.setRows(commissionLogMapper.listByParams(clp, new RowBounds(offset, limit)));
            logs.setTotal(total);
        }
        result.put("logs", logs);
        return result;
    }

    @Override
    public int updateByOrderId(Long orderId, Long productId) {
        return commissionLogMapper.updateByOrderId(orderId, productId);
    }

    @Override
    public int updateCommissionByOrderId(Long orderId) {
        return commissionLogMapper.updateCommissionByOrderId(orderId);
    }

    @Override
    public List<CommissionLog> selectByUserAgentCommission() {
        return commissionLogMapper.selectByUserAgentCommission();
    }

    @Override
    public int activeCommissionLog(Long orderId) {
        return commissionLogMapper.activeCommissionLog(orderId);
    }
}
